#include "BattlePredictor.hpp"
#include <algorithm>

using namespace BWAPI;
using namespace std;

BPUnit::BPUnit(
	BWAPI::Unit *u
)
{
	m_BWAPIUnit = u;
	m_HP = u->getHitPoints();
	WeaponType weaponType = u->getType().groundWeapon();
	m_groundDPF = double(weaponType.damageAmount()) / double(weaponType.damageCooldown());
	m_groundDPFPerHP = m_groundDPF / m_HP;
//	Broodwar->printf("BPUnit: %s groundDPF=%.2f HP=%.0f",u->getType().c_str(), m_groundDPF, m_HP);
}

BattlePredictor::BattlePredictor()
{
}

void BattlePredictor::addUnit(
	BWAPI::Unit *u
)
{
	if ( u->getPlayer() == Broodwar->self() ) {
		m_units.push_back( BPUnit(u) );
	} else if ( u->getPlayer() == Broodwar->enemy() ) {
		m_enemyUnits.push_back( BPUnit(u) );
	}
}

void BattlePredictor::simulationStep(
	std::vector<BPUnit> &myUnits,
	std::vector<BPUnit> &enemyUnits
) const
{
	double myDPF = 0;
	for (int i=0 ; i<myUnits.size() ; i++) {
		myDPF += myUnits[i].m_groundDPF;
	}
	double enemyDPF = 0;
	for (int i=0 ; i<enemyUnits.size() ; i++) {
		enemyDPF += enemyUnits[i].m_groundDPF;
	}
	myUnits.front().m_HP -= enemyDPF;
	if (myUnits.front().m_HP<=0.0) {
		myUnits.erase( myUnits.begin() );
//		Broodwar->printf("myUnit killed");
	}
	enemyUnits.front().m_HP -= myDPF;
	if (enemyUnits.front().m_HP<=0.0) {
		enemyUnits.erase( enemyUnits.begin() );
//		Broodwar->printf("enemyUnit killed");
	}
}

void BattlePredictor::runSimulation()
{
	sort(m_units.begin(), m_units.end());
	sort(m_enemyUnits.begin(), m_enemyUnits.end());
	vector<BPUnit> myUnits = m_units;
	vector<BPUnit> enemyUnits = m_enemyUnits;
	while (myUnits.size()>0 && enemyUnits.size()>0) {
		simulationStep(
			myUnits,
			enemyUnits);
	}
	Broodwar->printf("simulation result: %d myUnits, %d enemyUnits", myUnits.size(), enemyUnits.size());
}
